package com.cbgolf.oa.net;

import android.util.Log;
import com.cbgolf.oa.util.CollectionUtil;
import com.cbgolf.oa.util.DataUtil;
import com.cbgolf.oa.util.TextUtil;
import com.cbgolf.oa.util.Util;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Dispatcher;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;

/**
 * @author net request
 */
public class Web {

  public static OkHttpClient okHttpClient;

  public static final int TIMEOUT = 60000;

  public static final String TOKEN = "X-Auth-Token";

  /**
   * 发送get请求
   */
  public static <T> Callback.Cancelable get(String url, Map<String, String> map,
      Callback.CommonCallback<T> callback) {
    RequestParams params = new RequestParams(url);
    if (null != map) {
      for (Map.Entry<String, String> entry : map.entrySet()) {
        params.addQueryStringParameter(entry.getKey(), entry.getValue());
      }
    }
    Callback.Cancelable cancelable = x.http().get(params, callback);
    return cancelable;
  }

  /**
   * 发送post请求
   */
  public static <T> Callback.Cancelable post(String url, Map<String, String> map,
      Callback.CommonCallback<T> callback) {
    RequestParams params = new RequestParams(url);
    if (null != map) {
      for (Map.Entry<String, String> entry : map.entrySet()) {
        params.addParameter(entry.getKey(), entry.getValue());
      }
    }
    Callback.Cancelable cancelable = x.http().post(params, callback);
    return cancelable;
  }

  /**
   * 上传文件
   */
  public static <T> Callback.Cancelable upLoadFile(String url, Map<String, Object> map,
      Callback.CommonCallback<T> callback) {
    RequestParams params = new RequestParams(url);
    if (null != map) {
      for (Map.Entry<String, Object> entry : map.entrySet()) {
        params.addParameter(entry.getKey(), entry.getValue());
      }
    }
    params.setMultipart(true);
    Callback.Cancelable cancelable = x.http().get(params, callback);
    return cancelable;
  }

  /**
   * 下载文件
   */
  public static <T> Callback.Cancelable downLoadFile(String url, String filepath,
      Callback.CommonCallback<T> callback) {
    RequestParams params = new RequestParams(url);
    //设置断点续传
    params.setAutoResume(true);
    params.setSaveFilePath(filepath);
    Callback.Cancelable cancelable = x.http().get(params, callback);
    return cancelable;
  }

  public static void getClient() {
    if (null == okHttpClient) {
      okHttpClient = buildHttpClient();
    }
  }

  private static String getParams(Map<String, String> map) {
    StringBuilder sb = new StringBuilder();
    if (!CollectionUtil.mapIsNull(map)) {
      for (Map.Entry<String, String> me : map.entrySet()) {
        if (Util.isEqualsIgnoreCase("token", me.getKey())) {
          continue;
        }
        sb.append(me.getKey() + "=").append(me.getValue() + "&");
      }
    }
    String params = sb.toString();
    if (!Util.isNull(params) && params.length() > 0) {
      params = params.substring(0, params.length() - 1);
    }
    return params;
  }


  public static void getOK(final String url, final Map<String, String> map,
      final NetCallBack callBack) {
    getClient();
    String newUrl = url + "?" + getParams(map);
    Log.e("requestUrl:", newUrl + "");
    Request request = new Request.Builder()
        .url(newUrl)
        .addHeader("X-Auth-Token", TextUtil.Text(DataUtil.getToken()))
        .tag(url).build();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new okhttp3.Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        if (null != callBack) {
          callBack.onFailure(call, e);
        }
      }

      @Override
      public void onResponse(Call call, Response response) {
        if (null != callBack) {
          callBack.onResponse(call, response);
        }
      }
    });
  }

  public static void getOK(final String url, final NetCallBack callBack) {
    getClient();
    Log.e("requestUrl:", url + "");
    Request request = new Request.Builder()
        .url(url)
        .addHeader("X-Auth-Token", TextUtil.Text(DataUtil.getToken()))
        .build();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new okhttp3.Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        if (null != callBack) {
          callBack.onFailure(call, e);
        }
      }

      @Override
      public void onResponse(Call call, Response response) {
        if (null != callBack) {
          callBack.onResponse(call, response);
        }
      }
    });
  }

  public static void getOK(final String url, final Map<String, String> header,
      final Map<String, String> map, final NetCallBack callBack) {
    getClient();
    String key = null;
    String value = null;
    if (!CollectionUtil.mapIsNull(header)) {
      for (Map.Entry<String, String> me : header.entrySet()) {
        key = me.getKey();
        value = me.getValue();
      }
    }
    String newUrl = url + "?" + getParams(map);
    Log.e("requestUrl:", newUrl + "");
    Request request = new Request.Builder()
        .url(newUrl)
        .addHeader(TextUtil.Text(key), TextUtil.Text(value))
        .tag(url).build();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new okhttp3.Callback() {

      @Override
      public void onFailure(Call call, IOException e) {
        if (null != callBack) {
          callBack.onFailure(call, e);
        }
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        if (null != callBack) {
          callBack.onResponse(call, response);
        }
      }
    });
  }

  public static void postOk(String url, final NetCallBack callBack) {
    postOk(url, null, callBack);
  }

  public static void postOk(String url, Map<String, String> map, final NetCallBack callBack) {
    getClient();
    String newUrl = url + "?" + getParams(map);
    Log.e("requestUrl:", newUrl + "");
    FormBody.Builder builder = new FormBody.Builder();
    if (!CollectionUtil.mapIsNull(map)) {
      for (Map.Entry<String, String> me : map.entrySet()) {
        if (Util.isEqualsIgnoreCase("token", me.getKey())) {
          continue;
        }
        builder.add(TextUtil.Text(me.getKey()), TextUtil.Text(me.getValue()));
      }
    }
    FormBody body = builder.build();
    Request request = new Request.Builder()
        .url(url)
        .addHeader("X-Auth-Token", TextUtil.Text(DataUtil.getToken()))
        .tag(url).post(body).build();
    okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        if (null != callBack) {
          callBack.onFailure(call, e);
        }
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        if (null != callBack) {
          callBack.onResponse(call, response);
        }
      }
    });
  }

  public static void postJsonOk(String url, Map<String, Object> map, final NetCallBack callBack) {
    getClient();
    RequestBody requestBody = null;
    StringBuilder sb = new StringBuilder();
    if (!CollectionUtil.mapIsNull(map)) {
      for (Map.Entry<String, Object> me : map.entrySet()) {
        if (Util.isEqualsIgnoreCase("token", me.getKey())) {
          continue;
        }
        requestBody = RequestBody.create(MediaType.
                parse("application/json;charset=utf-8"),
            String.valueOf(me.getValue()));
        sb.append(me.getKey() + "=").append(me.getValue() + "&");
      }
    }

    String params = sb.toString();
    if (!Util.isNull(params) && params.length() > 0) {
      params = params.substring(0, params.length() - 1);
    }
    String newUrl = url + "?" + params;
    Log.e("requestUrl:", newUrl + "");
    Request request = new Request.Builder().url(url)
        .addHeader("X-Auth-Token", TextUtil.Text(DataUtil.getToken())).tag(url)
        .post(requestBody).build();

    okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        if (null != callBack) {
          callBack.onFailure(call, e);
        }
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        if (null != callBack) {
          callBack.onResponse(call, response);
        }
      }
    });
  }

  public static void deleteOk(String url, final NetCallBack callBack) {
    getClient();
    Log.e("requestUrl:", url + "?");
    Request request = new Request.Builder()
        .url(url)
        .delete()
        .addHeader("X-Auth-Token", TextUtil.Text(DataUtil.getToken())).tag(url)
        .build();
    okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        if (null != callBack) {
          callBack.onFailure(call, e);
        }
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        if (null != callBack) {
          callBack.onResponse(call, response);
        }
      }
    });
  }

  public static void putOk(String url, final NetCallBack callBack) {
    putOk(url, null, callBack);
  }

  public static void putOk(String url, Map<String, String> map, final NetCallBack callBack) {
    getClient();
    String newUrl = url + "?" + getParams(map);
    Log.e("requestUrl:", newUrl + "");
    MultipartBody requestBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("", "")
        .build();
    Request request = new Request.Builder()
        .url(newUrl)
        .put(requestBody)
        .addHeader("X-Auth-Token", TextUtil.Text(DataUtil.getToken()))
        .tag(url)
        .build();
    okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        if (null != callBack) {
          callBack.onFailure(call, e);
        }
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        if (null != callBack) {
          callBack.onResponse(call, response);
        }
      }
    });

  }
//    public static void putOk(String url, Map<String, Object> map, final NetCallBack callBack) {
//        getOkClient();
//        Object obj = null;
////        MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
//        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
//        RequestBody requestBody = null;
//        StringBuilder sb = new StringBuilder();
//        if (!CollectionUtil.mapIsNull(map)) {
//            for (Map.Entry<String, Object> me : map.entrySet()) {
//                if (Util.isEqualsIgnoreCase("token", me.getKey())) continue;
//                obj = me.getValue();
//                sb.append(obj.toString() + "");
//            }
//        }
//        Log.e("requestUrl:", url + "?" + sb.toString());
//        if (null != mediaType) requestBody = RequestBody.create(mediaType, String.valueOf(obj));
//        Request request = new Request.Builder()
//                .url(url)
//                .put(requestBody)
//                .addHeader("X-Auth-Token", TextUtil.Text(DataUtil.getToken())).tag(url)
//                .build();
//
//        okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
//            @Override
//            public void onFailure(Call call, IOException e) {
//                if (null != callBack) callBack.onFailure(call, e);
//            }
//
//            @Override
//            public void onResponse(Call call, Response response) throws IOException {
//                if (null != callBack) callBack.onResponse(call, response);
//
//            }
//        });
//
//    }

  public static void putjsonOk(String url, final NetCallBack callBack) {
    putjsonOk(url, null, callBack);
  }

  public static void putjsonOk(String url, Map<String, Object> map, final NetCallBack callBack) {
    getClient();
    Object obj = null;
    MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
    RequestBody requestBody = null;
    StringBuilder sb = new StringBuilder();
    if (!CollectionUtil.mapIsNull(map)) {
      for (Map.Entry<String, Object> me : map.entrySet()) {
        if (Util.isEqualsIgnoreCase("token", me.getKey())) {
          continue;
        }
        obj = me.getValue();
        sb.append(obj.toString() + "");
      }
    }
    Log.e("requestUrl:", url + "?" + sb.toString());
    if (null != mediaType) {
      requestBody = RequestBody.create(mediaType, String.valueOf(obj));
    }
    Request request = new Request.Builder()
        .url(url)
        .put(requestBody)
        .addHeader("X-Auth-Token", TextUtil.Text(DataUtil.getToken())).tag(url)
        .build();

    okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        if (null != callBack) {
          callBack.onFailure(call, e);
        }
      }

      @Override
      public void onResponse(Call call, Response response) {
        if (null != callBack) {
          callBack.onResponse(call, response);
        }

      }
    });

  }

  public static OkHttpClient buildHttpClient() {
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .addInterceptor(chain -> {
          Request request = chain.request();
          Response response = chain.proceed(request);
          return response;
        })
        .connectTimeout(30000 * 2, TimeUnit.MILLISECONDS)
        .readTimeout(30000 * 2, TimeUnit.MILLISECONDS)
        .writeTimeout(30000 * 2, TimeUnit.MILLISECONDS)
        .build();
    return okHttpClient;
  }


  public static void cancelAll(List<String> listUrls) {
    if (Util.listIsNull(listUrls)) {
      return;
    }
    Dispatcher dispatcher = okHttpClient.dispatcher();
    for (String url : listUrls) {
      synchronized (dispatcher) {
        for (Call call : dispatcher.queuedCalls()) {
          if (url.equals(call.request().tag())) {
            call.cancel();
          }
        }
        for (Call call : dispatcher.runningCalls()) {
          if (url.equals(call.request().tag())) {
            call.cancel();
          }
        }
      }
    }
  }

  public static void cancel(Object tag) {
    if (Util.isNull(tag)) {
      return;
    }
    Dispatcher dispatcher = okHttpClient.dispatcher();
    synchronized (dispatcher) {
      for (Call call : dispatcher.queuedCalls()) {
        if (tag.equals(call.request().tag())) {
          call.cancel();
        }
      }
      for (Call call : dispatcher.runningCalls()) {
        if (tag.equals(call.request().tag())) {
          call.cancel();
        }
      }
    }
  }

}



